Analog clock (extended)
This program is an extended version of the Analog Clock. It uses the exact same lines as that version, however it's expanded by all the timezones of the world. This page shows how the code works Needed commands This program uses all kinds of commands; however some or rarely used in other programs, so they deserve extra information. getTime→lTIME: stores the time into a list, for example lTIME. The hours are stored in lTIME(1), the minutes in lTIME(2) and the seconds in lTIME(3). getDate→lDATE: stores the date into a list, for example lDATE. The years are stored in lDATE(1), the months in lDATE(2) and the days in lDATE(3). Of course that are not the only commands used, but you should be familiar with IF-loops and Goto lbl's, before you start with this program. Purpose of this program First of all, we want the program to display the time. This part is covered in the other version. However, we want to have some more built-in functions aswell. If we, for example, want to know what time it is at the other side of the world, this program covers that too. At the beginning of the program, we have a short input part, in which we can enter the information the calculator need to know, in order to display the right time for the right timezone. This will add some new functions, but it makes starting up the clock a bigger deal then it was. That's why the last used settings are stored into a list, which you can use to start up the clock much faster. Lastly, we also add a digital timer at the side of the screen, just for the user to choose between the analog and the digital version. Now, we know what the program will have to do, so we can begin programming. Code analysis First of all, we want to make the program Mirage OS compatible. That's why we add :" at the first line and write the description just behind that. Do type that : at the beginning of the line, otherwize it won't work. :"An analog clock Next, we add a label. When we end the clock, we want it to return to the beginning, in stead of stopping the whole program. Lbl 0 After that's done, we want to display a menu, in which you can choose between the old settings, new ones and exit the program. ClrHome Menu("Analog clock:","Old settings",O,"New settings",N,"Exit",E) New settings First, we begin with the new settings. It spares some lines, making the program smaller. Lbl N -13 C This makes sure you'll be able to enter new settings. You'll see: While (int©≠C or C 14 or C -12) and C≠-10.5 and C≠-9.5 and C≠4.5 and C≠-3.5 and C≠3.5 and C≠4.5 and C≠5.5 and C≠5.75 and C≠6.5 and C≠9.5 and C≠10.5 and C≠11.5 and C≠12.75 Disp "Current timezone" Input "-12 - 14: ",C Disp "Wrong!" End This is the first while-loop. Here, you can enter the current timezone. When you enter a wrong value, the calculator will show Wrong! and you have to enter the current timezone again. ClrHome Menu("Daylights Savings Time?","Yes",W1,"No",W2) Lbl W1 1 G Goto WA Lbl W2 0 G After you enter a good timezone, the calculator asks you if it's daylights savings time. When a country doesn't use daylights savings time, the answer is always no. However, when a country does use the daylights savings time, you still will have to enter no. Only when the country uses daylights savings time and it's actually daylights savings time, you enter yes. When you enter yes, 1 will be stored into G. Otherwize, 0 will be stored into G. The reason why there's no goto command after 0 G is that it'll automaticaly go to the next label, since it's placed directly under: Lbl WA -13 T The same as the previous time: -13 makes sure the while loop won't skip before you have entered something: (int©≠C or C 14 or C -12) and C≠-10.5 and C≠-9.5 and C≠4.5 and C≠-3.5 and C≠3.5 and C≠4.5 and C≠5.5 and C≠5.75 and C≠6.5 and C≠9.5 and C≠10.5 and C≠11.5 and C≠12.75 Disp "Timezone" Input "-12 - 14: ",T Disp "Wrong!" End The same while-loop as the previous one, although there are some differences. You're not entering the current timezone here, but the timezone you want to know the time from, which is stored in variable T in stead of C. And, of course, when you enter a wrong timezone, the calculator will display Wrong!. ClrHome Menu("Daylights Savings Time?","Yes",W3,"No",W4) Lbl W3 1 I Goto WB Lbl W4 0 I The same menu is shown again. When you enter yes, 1 will be stored to I, otherwize 0 will be stored to I. Lbl WB C ANCL(1) T ANCL(2) G ANCL(3) I ANCL(4) All the values you entered are stored in list ANCL. Old settings This is where the old settings come in. Please notice that the new settings option also passes this part, because there is no goto command after the previous part of the code. Lbl O ANCL(1) C ANCL(2) T ANCL(3) G ANCL(4) I This returns all the saved settings and stores them back into variables. Now we have all the required inputs. However, we need to store them all into one variable, which can be used to modify the time. T-C E This stores the difference in timezones into variable E. G-I J This stores the difference in wintertime into variable J. E+J E This adds both variables and stores it, again, into variable E. Now, we have modified all variables into variable E. Now we can actually start displaying the clock. The actual clock This is the part where we're actually going to create the clock. pgrmGRAPHCLR This is what I entered, but I'll show what is included in that program: FnOff 1,2,3,4,5,6,7,8,9,0 94 Xmax:0 Xmin 62 Ymax:0 Ymin CoordOff AxesOff ExprOff ClrDraw Func FnOff 0,1,2,3,4,5,6,7,8,9 PlotsOff 1,2,3 Full Return Because it's quite long and I could use that in other programs, I decided to put that in another program. What this basicly does, is storing the functions in lWIND, then deleting all the functions, clearing the whole graphscreen. Now, we'll continue with the program: Xmax/2 Xmax Ymax/2 Ymax -Xmax Xmin -Ymax Ymin This part sets (0,0) as the middle of the screen. Degree Makes sure the mode is set to degree. 15 H:20 M:18 S This sets the length of the hands. Circle(0,0,30) Draws a circle, with the middle at (0,0), middle of the screen, and with a radius of 30. For(X,1,12) Text(28-int(cos(X*30)*25),46+int(sin(X*30)*25),X) End Texts the numbers of the clock. 28- and 46+ are needed because Text( doesn't use the axes to determine it's position. {0,0,0} ANG This deletes ANG. This didn't use any of the settings entered above. But that's gonna change: If T=-12:Then Text(57,1,"-12") Text(57,61,"Bakersisl.") End If T=-11:Then Text(57,1,"-11") Text(57,75,"Samoa") End If T=-10:Then Text(57,1,"-10") Text(57,63,"Honolulu") End If T=-9.5:Then Text(57,1,"-9:30") Text(57,63,"Marquesa") End If T=-9:Then Text(57,1,"-9,AKST") Text(57,71,"Alaska") End If T=-8:Then Text(57,1,"-8,PST") Text(57,83,"L.A.") End If T=-7:Then Text(57,1,"-7,MST") Text(57,71,"Denver") End If T=-6:Then Text(57,1,"-6,CST") Text(57,67,"Chicago") End If T=-5:Then Text(57,1,"-5,EST") Text(57,66,"New York") End If T=-4.5:Then Text(57,1,"-4:30") Text(57,67,"Caracas") End If T=-4:Then Text(57,1,"-4,AST") Text(57,63,"Santiago") End If T=-3.5:Then Text(57,1,"-3:30") Text(57,61,"Nwfound.") End If T=-3:Then Text(57,1,"-3") Text(57,64,"Buenos A.") End If T=-2:Then Text(57,1,"-2") Text(57,63,"Hamilton") End If T=-1:Then Text(57,1,"-1") Text(57,59,"Mid-Atlan") End If T=0:Then Text(57,1,"0,WET,GMT") Text(57,71,"London") End If T=1:Then Text(57,1,"+1,CET") Text(57,71,"Berlin") End If T=2:Then Text(57,1,"+2,EET") Text(57,71,"Athens") End If T=3:Then Text(57,1,"+3") Text(57,71,"Moscow") End If T=3.5:Then Text(57,1,"+3:30") Text(57,67,"Tehran") End If T=4:Then Text(57,1,"+4") Text(57,62,"Abu Dhabi") End If T=4.5:Then Text(57,1,"+4:30") Text(57,75,"Kabul") End If T=5:Then Text(57,1,"+5") Text(57,59,"Islamabad") End If T=5.5:Then Text(57,1,"+5:30") Text(57,71,"Mumbai") End If T=5.75:Then Text(57,1,"+5:45") Text(57,59,"Kathmandu") End If T=6:Then Text(57,1,"+6") Text(57,75,"Dhaka") End If T=6.5:Then Text(57,1,"+6:30") Text(57,67,"Rangoon") End If T=7:Then Text(57,1,"+7") Text(57,67,"Bangkok") End If T=8:Then Text(57,1,"+8,AWST") Text(57,62,"Hong Kong") End If T=9:Then Text(57,1,"+9") Text(57,75,"Seoul") End If T=9.5:Then Text(57,1,"+9:30,ACST") Text(57,63,"Adelaide") End If T=10:Then Text(57,1,"+10,AEST") Text(57,63,"Canberra") End If T=10.5:Then Text(57,1,"+10:30") Text(57,62,"Lord Hawe") End If T=11:Then Text(57,1,"+11") Text(57,67,"Honiara") End If T=11.5:Then Text(57,1,"+11:30") Text(57,63,"Kingston") End If T=12:Then Text(57,1,"+12") Text(57,55,"Wellington") End If T=12.75:Then Text(57,1,"+12:45") Text(57,63,"Waitangi") End If T=13:Then Text(57,1,"+13") Text(57,75,"Tonga") End If T=14:Then Text(57,1,"+14") Text(57,64,"Line isl.") End This is the timezone database. It displays the number of the timezone, and it's corresponding city. 0 F Just storing 0 into F. You'll see why this is needed in a minute. While getKey=0 This is the beginning of a while-menu. It only quits when a key is pressed, because getKey won't be 0 then. getTime TIME This is where the time is stored in TIME. TIME(1) = hours, TIME(2) = minutes and TIME(3) = seconds. If E≠int(E):Then If E isn't the same as int(E), we need an if-loop. That's because the E is the number of hours that indicates the number of hours that needs to be changed. When the number of hours isn't a whole number, however, you'd get half hours, and that's undisplayable. If E-.5=int(E-.5):Then E-.5 E 30 F If E = x.5, then -0.5 is added to E, and 30 is stored into F. F indicates the number of minutes that needs to be added by the way. Else If E-.25=int(E-.25):Then E-.25 E 15 F If E = x.25, then -0.25 is added to E and 15 is stored into F. Else E-.75 E 45 F End End End If E = x.75, then -0.75 is added to E and 45 is stored into F. The 3 ends at the end indicate the end of this If-menu. Just a simple counting shows that there were 3 Ifs before aswell. getDate DATE This stores the date into DATE. DATE(1) = years, DATE(2) = months and DATE(3) = days. TIME(1)+E TIME(1) TIME(2)+F TIME(2) This adds the two variables to the actual time. This is actually a source of A LOT of problems. Suppose it's 00:00:01, and it's the 1st of January, 2011. You wanna know the time in timezone -12, while you are in timezone +1. Then, when you add E to TIME(1), the hours become -13. This needs to be added to 24 and the date must be set one day back, so that it's the 0th of January, 2011. This is impossible, so the days have to be added to 31, because December has 31 days, and the months have to be set 1 back: the 31st of the 0th month 2011. So: the months have to be added to 12, and the years have to be set 1 back: the 31st of december 2010. This involves many lines of programming, and I haven't even talked about leap years yet... If TIME(2)>59:Then TIME(2)-60 TIME(2) TIME(1)+1 TIME(1) End If the number of minutes gets greater then 59, -60 is added to the minutes, and 1 is added to the hours. If TIME(2)<0:Then TIME(2)+60 TIME(2) TIME(1)-1 TIME(1) End If the number of minutes gets smaller then 0, 60 is added to minutes and -1 is addded to the hours. If TIME(1)>23:Then TIME(1)-24 TIME(1) DATE(3)+1 DATE(3) End If TIME(1)>23:Then TIME(1)-24 TIME(1) DATE(3)+1 DATE(3) End If TIME(1)>23:Then TIME(1)-24 TIME(1) DATE(3)+1 DATE(3) End If the number of hours gets greater then 23, -24 is added to the hours and 1 is added to the days. If TIME(1)<0:Then TIME(1)+24 TIME(1) DATE(3)-1 DATE(3) End If TIME(1)<0:Then TIME(1)+24 TIME(1) DATE(3)-1 DATE(3) End If TIME(1)<0:Then TIME(1)+24 TIME(1) DATE(3)-1 DATE(3) End If the number of hours gets smaller then 0, 24 is added to the hours and -1 is added to the days. If DATE(2)=1 or DATE(2)=3 or DATE(2)=5 or DATE(2)=7 or DATE(2)=8 or DATE(2)=10 or DATE(2)=12:Then If we're in a month which has 31 days as it's maximum, then... If DATE(3)>31:Then DATE(3)-31 DATE(3) DATE(2)+1 DATE(2) End If there are more then 31 days, then -31 will be added to the days and 1 will be added to the months. If DATE(3)<1:Then If there is less then 1 day, then... If DATE(2)=1 or DATE(2)=8:Then DATE(3)+31 DATE(3) DATE(2)-1 DATE(2) If it's January or August, then add 31 to the days and -1 to the months. Else If DATE(2)=3:Then If it's March, then... If DATE(1)/4=int( DATE(1)/4) and DATE(1)/100≠int( DATE(1)/100):Then If DATE(1)/1000=int( DATE(1)/1000):Then DATE(3)+29 DATE(3) DATE(2)-1 DATE(2) If it's a leap year, then add 29 to the days, and -1 to the months. Else Goto N1 End If it's not a leap year, go to label N1. Else Lbl N1 DATE(3)+28 DATE(3) DATE(2)-1 DATE(2) End If it's not a leap year, 28 is added to the days, and -1 is added to the months. Else DATE(3)+30 DATE(3) DATE(2)-1 DATE(2) End End End If it's not January, nor August, nor March (and it's a month with 31 days max, and there is less than 1 day, you remember?), then add 30 to the days and -1 to the months. After all these If-loops, I've lost track of the number of Ends I need to use, but it seems like 3 does it:) Else If DATE(2)=2:Then So, let me get this straight: if it's not January, nor March, nor May, nor July, nor August, nor October, nor December, then..., that's what that Else does. If it's February, then... If DATE(1)/4=int( DATE(1)/4) and DATE(1)/100≠int( DATE(1)/100):Then If DATE(1)/1000=int( DATE(1)/1000):Then If it's a leap year, then... If DATE(3)>29:Then DATE(3)-29 DATE(3) DATE(2)+1 DATE(2) End If there are more than 29 days, then add -29 to the days and 1 to the months. If DATE(3)<1:Then DATE(3)+31 DATE(3) DATE(2)-1 DATE(2) End If there is less than 1 day, 31 is added to the days, and -1 is added to the months. The reason why I need a relatively small if-loop for this is that there is only 1 month which has 29 days. And there is only one possible month before February, January, which always has 31 as its max.. God be praised:). Else Goto NS End If it's not a leap year, then go to label NS. Else Lbl NS If DATE(3)>28:Then DATE(3)-28 DATE(3) DATE(2)+1 DATE(2) End If it's not a leap year and February has more than 28 days, -28 is added to the days and 1 to the months. If DATE(3)<1:Then DATE(3)+31 DATE(3) DATE(2)-1 DATE(2) End End If February has less then 1 day, add 31 to the days and -1 to the months. Else If DATE(3)>30:Then DATE(3)-30 DATE(3) DATE(2)+1 DATE(2) End Hmm... That Else indicates that it isn't January, nor February, nor March, nor May, nor July, nor August, nor October, nor December. So, we're only talking about months which have 30 days as their maximum. If there are more than 30 days, -30 will be added to the days, and 1 will be added to the months. If DATE(3)<1:Then DATE(3)+31 DATE(3) DATE(2)-1 DATE(2) End End End If there is less than 1 day, 30 days will be added to the days and -1 to the months. Here, we neither need a large if-loop, because before months which have 30 days as their maximum, only months with a maximum of 31 days can be before it. Those three ends seem to work here, they finally define the end of this large if-loop, which began with the months which have 31 as their max. Do you still remember that?:) If DATE(2)>12:Then DATE(2)-12 DATE(2) DATE(1)+1 DATE(1) End If there are more than 12 months, -12 is added to the months and 1 to the years. If DATE(2)<1:Then DATE(2)+12 DATE(2) DATE(1)-1 DATE(1) End If there is less than 1 month, 12 is added to the months and -1 to the years. Now, we've finally converted all the values, which indicate the time and date, into good numbers, which can be displayed by the clock. Next, we're gonna display the analog clock: If TIME(3)≠ ANG(3)/6:Line(0,0,sin( ANG(3))*S,cos( ANG(3))*S,0) If TIME(2)≠ ANG(2)/6:Then Line(0,0,sin( ANG(2))*M,cos( ANG(2))*M,0) Line(0,0,sin( ANG(1))*H,sin( ANG(1))*H,0) End TIME(1)*30+ TIME(2)/2 ANG(1) TIME(2)*6 ANG(2) TIME(3)*6 ANG(3) Line(0,0,sin( ANG(1))*H,cos( ANG(1))*H) Line(0,0,sin( ANG(2))*M,cos( ANG(2))*M) Line(0,0,sin( ANG(3))*S,cos( ANG(3))*S) This draws the actual clock. Look for information about this part in the regular Analog Clock. Text(0,1,"Year:") Text(6,1,"Mnth:") Text(12,1,"Day:") Text(18,1,"Hour:") Text(24,1,"Min:") Text(30,1,"Sec:") This texts some text at the upper-left corner of the display. Text(0,79, DATE(1)) If DATE(2)<10:Then Text(6,87,"0") Text(6,91, DATE(2)) Else Text(6,87, DATE(2)) End If DATE(3)<10:Then Text(12,87,"0") Text(12,91, DATE(3)) Else Text(12,87, DATE(3)) End If TIME(1)<10:Then Text(18,87,"0") Text(18,91, TIME(1)) Else Text(18,87, TIME(1)) End If TIME(2)<10:Then Text(24,87,"0") Text(24,91, TIME(2)) Else Text(24,87, TIME(2)) End If TIME(3)<10:Then Text(30,87,"0") Text(30,91, TIME(3)) Else Text(30,87, TIME(3)) End This displays the time digitally in the upper right corner of the screen. The reason that it's so much longer than the previous part which displayed some text, is that the calculator doesn't add a 0 in front of a number that is smaller than 10, so we need to add that 0 manually. If TIME(1)>11:Then Text(36,87,"PM") Else Text(36,87,"AM") End This displays AM or PM at the right side of the screen. End Hmmmm... This end indicates the end of the while menu, which is waaaay back, somewhere at the beginning. This End will only be passed when a key is pressed. Goto 0 When the clock is stopped, the program is restarted, by going back to Lbl 0, which was the first command of this program. So now we're done with the clock, but we're not done with everything. We just haven't done a small part yet. Exit When we select Exit in the main menu, we still need to have a Lbl E: Lbl E When you select Exit, you'll go to Lbl E, which is here. This is what I entered next... prgmGRAPHB because I use this program for other programs aswell. This is what it contains: CoordOn GridOff AxesOn LabelOff ExprOn ClrDraw Return So you can add this into your program aswell. ClrHome Clears the screen. Stop Stops the program. Finally! Important extra information I am not the author of the other version of the analog clock, and I do not try to steal eventual copyright of that program. Apart from that, I do not take responsibility for eventual faults in THOSE lines. However, when there is a fault in my program, please edit this page, and fix the fault. Please notice you can archive this (large) program and open it with Mirage OS. This will save space on your RAM memory. One last thing: I do not speak English natively, so I'd appreciate if you'd correct any spelling/grammar mistakes. I hope this helped you a lot. Category:Programing Examples